#ifndef C5230F35_B1B4_471E_9A33_FD41B2259AB6
#define C5230F35_B1B4_471E_9A33_FD41B2259AB6

#include <functional>
#include "Daemon.hpp"
#include "protocal.hpp"
#include "Servercal.hpp"
#include "Sock.hpp"

using func_t = std::function<std::string (std::string& package)>;

const int size = 4096;

class TcpServer{
public:
	TcpServer(uint16_t port,func_t func):
	port_(port),callback(func)
	{}
public:
	bool Init()
	{
		listenfd_.Socket();
		listenfd_.Bind(port_);
		listenfd_.Listen();
		return true;
	}
	void Start()
	{
		Daemon();
		// signal(SIGCHLD,SIG_IGN);
		// signal(SIGPIPE,SIG_IGN);
		while(1){
			std::string ip;
			uint16_t port;
			int sockfd = listenfd_.Accept(&ip,&port);
			lg(Info, "accept success,clientip:%s,clientport:%d",ip.c_str(),port);
			if(fork() == 0){
				listenfd_.Close();
				char buffer[size];
				std::string inbuffer_stream;
				while(true){
					int n = read(sockfd,buffer,sizeof(buffer));
					if(n < 0){
						lg(Fatal,"read error,errno:%d,errstring:%s",errno,strerror(errno));
						break;
					}
					else if(n == 0) break;
					else{
						buffer[n] = 0;
						inbuffer_stream += buffer;
						
						lg(Debug,"gets client request:%s",inbuffer_stream.c_str());
						while(true)
						{
							std::string info = callback(inbuffer_stream);
							// std::cout << info << std::endl;
							if(info.empty()){       //为空说明无完整报文，去再次读取
								break;
							}
							lg(Info,"have done,the response is : %s",info.c_str());
							// std::cout << "获得的结果:" << info << std::endl;
							write(sockfd,info.c_str(),info.size());
						}
					}
				}
				close(sockfd);
				exit(0);
			}
			close(sockfd);
		}
	}
private:
	// std::string ip_;
	uint16_t port_;
	Sock listenfd_;
	func_t callback;
};

#endif /* C5230F35_B1B4_471E_9A33_FD41B2259AB6 */
